home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 44 / PC Actual CD 44.iso / Linux / Cygwin / full.exe / Disk1 / data1.cab / Tools / share / tk8.0 / safetk.tcl < prev    next >
Encoding:
Text File  |  1998-12-04  |  4.6 KB  |  149 lines

  1. # safetk.tcl --
  2. #
  3. # Support procs to use Tk in safe interpreters.
  4. #
  5. # SCCS: @(#) safetk.tcl 1.8 97/10/29 14:59:16
  6. #
  7. # Copyright (c) 1997 Sun Microsystems, Inc.
  8. #
  9. # See the file "license.terms" for information on usage and redistribution
  10. # of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  11.  
  12. # see safetk.n for documentation
  13.  
  14. #
  15. #
  16. # Note: It is UNSAFE to let any untrusted code being executed
  17. #       between the creation of the interp and the actual loading
  18. #       of Tk in that interp.
  19. #       You should "loadTk $slave" right after safe::tkInterpCreate
  20. #       Otherwise, if you are using an application with Tk
  21. #       and don't want safe slaves to have access to Tk, potentially
  22. #       in a malevolent way, you should use 
  23. #            ::safe::interpCreate -nostatics -accesspath {directories...}
  24. #       where the directory list does NOT contain any Tk dynamically
  25. #       loadable library
  26. #
  27.  
  28. # We use opt (optional arguments parsing)
  29. package require opt 0.1;
  30.  
  31. namespace eval ::safe {
  32.  
  33.     # counter for safe toplevels
  34.     variable tkSafeId 0;
  35.  
  36.     #
  37.     # tkInterpInit : prepare the slave interpreter for tk loading
  38.     #
  39.     # returns the slave name (tkInterpInit does)
  40.     #
  41.     proc ::safe::tkInterpInit {slave} {
  42.     global env tk_library
  43.     if {[info exists env(DISPLAY)]} {
  44.         $slave eval [list set env(DISPLAY) $env(DISPLAY)];
  45.     }
  46.     # there seems to be an obscure case where the tk_library
  47.     # variable value is changed to point to a sym link destination
  48.     # dir instead of the sym link itself, and thus where the $tk_library
  49.     # would then not be anymore one of the auto_path dir, so we use
  50.     # the addToAccessPath which adds if it's not already in instead
  51.     # of the more conventional findInAccessPath
  52.     ::interp eval $slave [list set tk_library [::safe::interpAddToAccessPath $slave $tk_library]]
  53.     return $slave;
  54.     }
  55.  
  56.  
  57. # tkInterpLoadTk : 
  58. # Do additional configuration as needed (calling tkInterpInit) 
  59. # and actually load Tk into the slave.
  60. # Either contained in the specified windowId (-use) or
  61. # creating a decorated toplevel for it.
  62.  
  63. # empty definition for auto_mkIndex
  64. proc ::safe::loadTk {} {}
  65.    
  66.     ::tcl::OptProc loadTk {
  67.     {slave -interp "name of the slave interpreter"}
  68.     {-use  -windowId {} "window Id to use (new toplevel otherwise)"}
  69.     } {
  70.     if {![::tcl::OptProcArgGiven "-use"]} {
  71.         # create a decorated toplevel
  72.         ::tcl::Lassign [tkTopLevel $slave] w use;
  73.         # set our delete hook (slave arg is added by interpDelete)
  74.         Set [DeleteHookName $slave] [list tkDelete {} $w];
  75.     }
  76.     tkInterpInit $slave;
  77.     ::interp eval $slave [list set argv [list "-use" $use]];
  78.     ::interp eval $slave [list set argc 2];
  79.     load {} Tk $slave
  80.     # Remove env(DISPLAY) if it's in there (if it has been set by
  81.     # tkInterpInit)
  82.     ::interp eval $slave {catch {unset env(DISPLAY)}}
  83.     return $slave
  84.     }
  85.  
  86.     proc ::safe::tkDelete {W window slave} {
  87.     # we are going to be called for each widget... skip untill it's
  88.     # top level
  89.     Log $slave "Called tkDelete $W $window" NOTICE;
  90.     if {[::interp exists $slave]} {
  91.         if {[catch {::safe::interpDelete $slave} msg]} {
  92.         Log $slave "Deletion error : $msg";
  93.         }
  94.     }
  95.     if {[winfo exists $window]} {
  96.         Log $slave "Destroy toplevel $window" NOTICE;
  97.         destroy $window;
  98.     }
  99.     }
  100.  
  101. proc ::safe::tkTopLevel {slave} {
  102.     variable tkSafeId;
  103.     incr tkSafeId;
  104.     set w ".safe$tkSafeId";
  105.     if {[catch {toplevel $w -class SafeTk} msg]} {
  106.     return -code error "Unable to create toplevel for\
  107.         safe slave \"$slave\" ($msg)";
  108.     }
  109.     Log $slave "New toplevel $w" NOTICE
  110.  
  111.     set msg "Untrusted Tcl applet ($slave)"
  112.     wm title $w $msg;
  113.  
  114.     # Control frame
  115.     set wc $w.fc
  116.     frame $wc -bg red -borderwidth 3 -relief ridge ;
  117.  
  118.     # We will destroy the interp when the window is destroyed
  119.     bindtags $wc [concat Safe$wc [bindtags $wc]]
  120.     bind Safe$wc <Destroy> [list ::safe::tkDelete %W $w $slave];
  121.  
  122.     label $wc.l -text $msg \
  123.         -padx 2 -pady 0 -anchor w;
  124.  
  125.     # We want the button to be the last visible item
  126.     # (so be packed first) and at the right and not resizing horizontally
  127.  
  128.     # frame the button so it does not expand horizontally
  129.     # but still have the default background instead of red one from the parent
  130.     frame  $wc.fb -bd 0 ;
  131.     button $wc.fb.b -text "Delete" \
  132.         -bd 1  -padx 2 -pady 0 -highlightthickness 0 \
  133.         -command [list ::safe::tkDelete $w $w $slave]
  134.     pack $wc.fb.b -side right -fill both ;
  135.     pack $wc.fb -side right -fill both -expand 1;
  136.     pack $wc.l -side left  -fill both -expand 1;
  137.     pack $wc -side bottom -fill x ;
  138.  
  139.     # Container frame
  140.     frame $w.c -container 1;
  141.     pack $w.c -fill both -expand 1;
  142.     
  143.     # return both the toplevel window name and the id to use for embedding
  144.     list $w [winfo id $w.c] ;
  145. }
  146.  
  147. }
  148.